﻿namespace GuessTheAnswer.ConsoleUI;


/// <summary>
/// 控制台答题
/// </summary>
internal class ConsoleAnswer : Answer
{
    /// <summary>
    /// 答案分组数量
    /// </summary>
    public static int ResultSplitCount { get; set; } = 4;


    public ConsoleAnswer(AnswerTemplate template) : base(template)
    {

    }

    public void Start()
    {
        while(true)
        {
            Console.Clear();

            Display();

            if (IsAllCorrect())
            {
                Console.Write("答案已经全部正确!\n ");
                return;
            }

            try
            {
                CorrectSubjects(GetInputId());
                Next();
            }
            catch(Exception e)
            {
                Console.WriteLine($"{e.Message} 需要重新输入! 按任意键继续");
                Console.ReadLine();
            }
        }
    }

    private bool IsAllCorrect()
    {
        foreach(var i in Rounds)
        {
            if (!i.IsCorrect) return false;
        }

        return true;
    }

    private void CorrectSubjects(int[] ids)
    {
        foreach(var i in ids)
        {
            if(i >= Subjects.Length || i < 0)
            {
                throw new Exception($"id [ {i} ] 不在题目范围内");
            }
        }

        foreach(var i in ids)
        {
            Rounds[i].Correct();
        }

    }

    private void Display()
    {
        Console.WriteLine($"[{Template.Name}] 第{RoundNumber + 1}回合");

        ISubject? subject = null;


        int subject_count = Template.Subjects.Length;
        int line_id = 0;


        Console.WriteLine("\n参考答案\n");

        for(int cur = 0; cur < subject_count; cur++)
        {
            if(cur % ResultSplitCount == 0)
            {
                int start_id = line_id * ResultSplitCount + 1;

                Console.Write($"\n\n[{start_id:00}-{start_id + ResultSplitCount - 1:00}]:  ");

                line_id++;
            }

            if(Subjects[cur] != subject && subject != null)
            {
                int start_id = line_id * ResultSplitCount + 1;

                Console.Write($"\n\n[{start_id:00}-{start_id + ResultSplitCount:00}]:  ");

                line_id++;
            }


            Console.Write($"{Rounds[cur].RoundAnswer()} ");
        }

        Console.WriteLine("\n");
        Console.Write($"剩余不正确的题目序号是: ");


        for (int i = 0; i < Subjects.Length; i++)
        {
            if (!Rounds[i].IsCorrect)
            {
                Console.Write($"{i + 1} ");
            }
        }

        Console.WriteLine("\n");
    }

    private static int[] GetInputId()
    {
        Console.Write("请输入正确的题目ID用空格隔开 输入[C]跳过\n>> ");

        while (true)
        {
            var input = GetValidInput();
            if (input.ToLower() == "c") return Array.Empty<int>();


            var tokens = input.Split(' ');
            int[] input_id = Array.Empty<int>();

            try
            {
                input_id = ParserId(tokens);
            }
            catch
            {
                Console.WriteLine("输入有问题 请重新输入");
                continue;
            }


            Console.Write($"您输入的是: [ {string.Join(",", input_id)} ]\n正确请输入[Y] 错误请输入[R]\n>> ");
            var index = GetAppointInput(true, "Y", "R");


            if (index == 0)
            {
                return (from i in input_id select i - 1).ToArray();
            }
            if(index == 2)
            {
                return Array.Empty<int>();
            }

            Console.Write("请重新输入>> ");
        }

        //转换字符id到数字id
        static int[] ParserId(string[] tokens)
        {
            List<int> input_id = new();

            foreach (var i in tokens)
            {
                if (string.IsNullOrWhiteSpace(i))
                {
                    continue;
                }

                input_id.Add(int.Parse(i));
            }

            return input_id.ToArray();
        }

        //获取有效输入 非空字符串
        static string GetValidInput()
        {
            string? input = null;

            while (true)
            {
                input = Console.ReadLine()?.Trim();

                if(!string.IsNullOrWhiteSpace(input))
                {
                    return input;
                }

                Console.Write("请输入非空白字符串 >> ");
            }
        }

        //获取指定输入
        static int GetAppointInput(bool ignoreCase, params string[] tokens)
        {
            Func<string, string, bool> match = ignoreCase switch
            {
                true => (a, b) => a.ToLower() == b.ToLower(),
                false => (a, b) => a == b
            };

            while (true)
            {
                var input = GetValidInput();

                for(int i = 0; i < tokens.Length; i++)
                {
                    if(match(tokens[i], input))
                    {
                        return i;
                    }
                }

                Console.Write($"输入内容需包含[ {string.Join(",", tokens)} ] >> ");
            }
        }
    }
}
